
#include <mockcpp/mockcpp.hpp>
#include <testngpp/testngpp.hpp>
#include <Length.h>
#include <Volume.h>
#include <LengthUnit.h>
#include <VolumeUnit.h>
#include <Amount.h>
#include <LengthFormat.h>
#include <VolumeFormat.h>
#include <sstream>

USING_MOCKCPP_NS
USING_TESTNGPP_NS

FIXTURE(VolumeString_inBaseUnit)
{
	void Assert_EQ_VolumeString(string volumeString, Volume& volume)
	{
		VolumeFormat volumeFormat(volume, IN_BASE_UNIT);
		ostringstream volumeStream;
		volumeStream << volumeFormat;

		ASSERT_EQ(volumeString, volumeStream.str());
	}
	TEST( 1 OZ expressed as "6 TSP")
	{
		Volume volume(1, OZ);
		Assert_EQ_VolumeString("6 TSP", volume);
	}
	TEST( 3 TBSP expressed as "9 TSP")
	{
		Volume volume(3, TBSP);
		Assert_EQ_VolumeString("9 TSP", volume);
	}
	TEST( 3*1760+2 TSP expressed as "5282 TSP")
	{
		Volume volume(3*1760+2, TSP);
		Assert_EQ_VolumeString("5282 TSP", volume);
	}
	TEST( 0 OZ expressed as "0 TSP")
	{
		Volume volume(0, OZ);
		Assert_EQ_VolumeString("0 TSP", volume);
	}
};

FIXTURE(VolumeString_test)
{
	void Assert_EQ_VolumeString(string volumeString, Volume& volume)
	{
		VolumeFormat volumeFormat(volume, IN_ALL_UNIT);
		ostringstream volumeStream;
		volumeStream << volumeFormat;

		ASSERT_EQ(volumeString, volumeStream.str());
	}
	TEST( 5 TSP expressed as "1 TBSP 2 TSP")
	{
		Volume volume(5, TSP);
		Assert_EQ_VolumeString("1 TBSP 2 TSP", volume);
	}
	TEST( 23 TSP expressed as "3 OZ 1 TBSP 2 TSP")
	{
		Volume volume(23, TSP);
		Assert_EQ_VolumeString("3 OZ 1 TBSP 2 TSP", volume);
	}
	TEST( 0 OZ expressed as "0 TSP")
	{
		Volume volume(0, OZ);
		Assert_EQ_VolumeString("0 TSP", volume);
	}
};

FIXTURE(Volume_test)
{
	TEST(test 2 OZ + 10 TSP == 2*2*3+10 TSP)
	{
		Volume volume_1(2, OZ);
		Volume volume_2(10, TSP);
		Volume volume_3(22, TSP);
		ASSERT_TRUE(volume_1 + volume_2 == volume_3);
	}
	TEST(test 2 OZ + 10 FEET == INVALID_DATA)
	{
		Volume volume_1(2, OZ);
		Volume volume_2(10, FEET);
		ASSERT_TRUE(volume_1 + volume_2 == INVALID_DATA);
	}
	TEST(test 2 OZ == 2*2*3 TSP)
	{
		Volume volume_1(2, OZ);
		Volume volume_2(12, TSP);
		ASSERT_TRUE(volume_1 == volume_2);
	}
	TEST(test 2 OZ == 2*2*3 FEET)
	{
		Volume volume_1(2, OZ);
		Volume volume_2(12, FEET);
		ASSERT_TRUE(volume_1 != volume_2);
	}
	TEST(test 2 TBSP == 6 TSP)
	{
		Volume volume_1(2, TBSP);
		Volume volume_2(6, TSP);
		ASSERT_TRUE(volume_1 == volume_2);
	}
	TEST(test 2 OZ == 2 OZ)
	{
		Volume volume_1(2, OZ);
		Volume volume_2(2, OZ);
		ASSERT_TRUE(volume_1 == volume_2);
	}
	TEST(test 1 OZ != 2 OZ)
	{
		Volume volume_1(1, OZ);
		Volume volume_2(2, OZ);
		ASSERT_TRUE(volume_1 != volume_2);
	}
	TEST(test 1 OZ == 2 OZ is not true)
	{
		Volume volume_1(1, OZ);
		Volume volume_2(2, OZ);
		ASSERT_FALSE(volume_1 == volume_2);
	}
	TEST(test 1 OZ == 2 TBSP)
	{
		Volume volume_1(1, OZ);
		Volume volume_2(2, TBSP);
		ASSERT_TRUE(volume_1 == volume_2);
	}
	TEST(test 3 TBSP == 3 TBSP)
	{
		Volume volume_1(3, TBSP);
		Volume volume_2(3, TBSP);
		ASSERT_TRUE(volume_1 == volume_2);
	}
	TEST(test 3 TBSP != 4 TBSP)
	{
		Volume volume_1(3, TBSP);
		Volume volume_2(4, TBSP);
		ASSERT_TRUE(volume_1 != volume_2);
	}
};

FIXTURE(LengthString_inBaseUnit)
{
	void Assert_EQ_LengthString(string lengthString, Length& length)
	{
		LengthFormat lengthFormat(length, IN_BASE_UNIT);
		ostringstream lengthStream;
		lengthStream << lengthFormat;

		ASSERT_EQ(lengthString, lengthStream.str());
	}
	TEST( 5 FEET expressed as "5 FEET")
	{
		Length length(5, FEET);
		Assert_EQ_LengthString("5 FEET", length);
	}
	TEST( 1761 YARD expressed as "5283 FEET")
	{
		Length length(1761, YARD);
		Assert_EQ_LengthString("5283 FEET", length);
	}
	TEST( 3*1760+2 FEET expressed as "5282 FEET")
	{
		Length length(3*1760+2, FEET);
		Assert_EQ_LengthString("5282 FEET", length);
	}
	TEST( 0 MILE expressed as "0 FEET")
	{
		Length length(0, MILE);
		Assert_EQ_LengthString("0 FEET", length);
	}
};

FIXTURE(LengthString_test)
{
	void Assert_EQ_LengthString(string lengthString, Length& length)
	{
		LengthFormat lengthFormat(length, IN_ALL_UNIT);
		ostringstream lengthStream;
		lengthStream << lengthFormat;

		ASSERT_EQ(lengthString, lengthStream.str());
	}
	TEST( 5 FEET expressed as "1 YARD 2 FEET")
	{
		Length length(5, FEET);
		Assert_EQ_LengthString("1 YARD 2 FEET", length);
	}
	TEST( 1761 YARD expressed as "1 MILE 1 YARD")
	{
		Length length(1761, YARD);
		Assert_EQ_LengthString("1 MILE 1 YARD", length);
	}
	TEST( 3*1760+2 FEET expressed as "1 MILE 2 FEET")
	{
		Length length(3*1760+2, FEET);
		Assert_EQ_LengthString("1 MILE 2 FEET", length);
	}
	TEST( 0 MILE expressed as "0 FEET")
	{
		Length length(0, MILE);
		Assert_EQ_LengthString("0 FEET", length);
	}
};

FIXTURE(Length_test)
{
	TEST(test 1 MILE + 10 FEET == 3*1760+10 FEET)
	{
		Length length_1(1, MILE);
		Length length_2(10, FEET);
		Length length_3(3*1760+10, FEET);
		ASSERT_TRUE(length_1 + length_2 == length_3);
	}
	TEST(test 2 MILE == 2*1760 FEET)
	{
		Length length_1(2, MILE);
		Length length_2(6*1760, FEET);
		ASSERT_TRUE(length_1 == length_2);
	}
	TEST(test 2 YARD == 6 FEET)
	{
		Length length_1(2, YARD);
		Length length_2(6, FEET);
		ASSERT_TRUE(length_1 == length_2);
	}
	TEST(test 2 MILE == 2 MILE)
	{
		Length length_1(2, MILE);
		Length length_2(2, MILE);
		ASSERT_TRUE(length_1 == length_2);
	}
	TEST(test 1 MILE != 2 MILE)
	{
		Length length_1(1, MILE);
		Length length_2(2, MILE);
		ASSERT_TRUE(length_1 != length_2);
	}
	TEST(test 1 MILE == 2 MILE is not true)
	{
		Length length_1(1, MILE);
		Length length_2(2, MILE);
		ASSERT_FALSE(length_1 == length_2);
	}
	TEST(test 1 MILE == 1760 YARD)
	{
		Length length_1(1, MILE);
		Length length_2(1760, YARD);
		ASSERT_TRUE(length_1 == length_2);
	}
	TEST(test 3 YARD == 3 YARD)
	{
		Length length_1(3, YARD);
		Length length_2(3, YARD);
		ASSERT_TRUE(length_1 == length_2);
	}
	TEST(test 3 YARD != 4 YARD)
	{
		Length length_1(3, YARD);
		Length length_2(4, YARD);
		ASSERT_TRUE(length_1 != length_2);
	}
};


